import { Observable, Observer, Subscriber, filter } from 'rxjs';
import { BaseManager } from '../../libs/rxjs/cc3/BaseManager';
import { _decorator, color, director, System } from 'cc';
import { DevConfig } from '../DevConfig';
import { Timer } from '../../libs/rxjs/cc3/CreatorSchedule';
import { sys } from 'cc';
import { jsb_sdk_m } from './JsbSDKManager';
import { udm } from '../UserDataManager';
import { thinking_sdk_m } from './ThinkingCocosSDKManager';
import { gm } from '../GameManager';
import { timem } from '../TimeManager';
import { appsflyer_sdk_m } from './AppsFlyerSDKManager';
const { ccclass, property } = _decorator;

export type ProvideInfo = {
    noads?: number,
    coin?: number,
    inf_heart_sec?: number,
    noads_sec?: number,
    swapper?: number,
    magnet?: number,
    balloon?: number,

    dynamic_reward_id?: number,
};

export type IapProductInfo = {
    productId: string,
    price: number,

    provide: ProvideInfo,
    discount?: number,
    limited?: number, // 购买限制

    flag?: string,
    giftType?: string,
    localizedTitle?: string,

    iconId?: number,

    name: ''
};

@ccclass('IapSDKManager')
export class IapSDKManager extends BaseManager {

    public static instance: IapSDKManager;
    static ID = 'iap_sdk_system';
    get logColorOverride() { return color().fromHEX('#EE5555') };

    static registerSystem() {
        director.unregisterSystem(director.getSystem(IapSDKManager.ID));
        director.registerSystem(IapSDKManager.ID, iap_sdk_m, System.Priority.MEDIUM);
        iap_sdk_m.init();
    }

    onInitManager() {
        this.log('onInitManager', this.timestamp);
        if (sys.isNative) {
            jsb_sdk_m.registerMsg('IapSDKManager.canMake', this.canMake.bind(this));
            jsb_sdk_m.registerMsg('IapSDKManager.onPurchased', this.onPurchased.bind(this));
            jsb_sdk_m.registerMsg('IapSDKManager.onFailed', this.onFailed.bind(this));
            jsb_sdk_m.registerMsg('IapSDKManager.onRestored', this.onRestored.bind(this));
            jsb_sdk_m.registerMsg('IapSDKManager.productsResponse', this.productsResponse.bind(this));
            this.requestProductInfos();
        }
    }

    initialize() {
        jsb_sdk_m.sendMsg('IapSDK.initialize', '');
        this.checkUncompleted();
    }

    checkUncompleted() {
        udm.processingProductIds.value.forEach(productId => {
            let info = this.getIapProductInfoByProductId(productId);
            this.startPurchase(info, true).subscribe();
        });
    }

    requestProductInfos() {
        jsb_sdk_m.sendMsg('IapSDK.requestProductInfos', JSON.stringify({
            productIds: DevConfig.allProductIds
        }));
    }

    // 根据apple后台设定的数据重新刷新商品价格，附带填充后台设置的商品本地化标题
    productsResponse(args: string) {
        this.log('productsResponse', args);
        let productInfos: Record<string, { product_id: string, price: number, localizedTitle: string }> = JSON.parse(args);
        for (let productId in productInfos) {
            let info = productInfos[productId];
            for (let key in DevConfig.iap) {
                let iapProductInfo = DevConfig.iap[key] as IapProductInfo;
                if (iapProductInfo.productId == info.product_id) {
                    iapProductInfo.price = info.price * 100;
                    iapProductInfo.localizedTitle = info.localizedTitle;
                }
            }
        }
    }

    _observerMap: Record<string, Subscriber<{ status: string, id?: string }>> = {};

    startPurchase(iapProductInfo: IapProductInfo, noObserver = false): Observable<{ status: string, id?: string }> {
        this.log('startPurchase', JSON.stringify(iapProductInfo));
        return new Observable(observer => {
            if (DevConfig.IAP_AUTO_PASSED || !sys.isNative) {
                globalThis.LobbyManager.instance.customLoadingReasons.add(`iap_${iapProductInfo.flag}`);
                Timer(2).subscribe(_ => {
                    globalThis.LobbyManager.instance.customLoadingReasons.delete(`iap_${iapProductInfo.flag}`);
                    observer.nextAndComplete({ status: 'success', id: null });
                });
            } else {
                // TODO: 接入支付SDK
                if (sys.isNative) {
                    if (sys.platform == sys.Platform.IOS) {
                        this.log('startPurchase native ios', JSON.stringify(iapProductInfo));
                        udm.processingProductIds.value.push(iapProductInfo.productId);
                        udm.save();
                        if (!noObserver) {
                            this._observerMap[iapProductInfo.productId] = observer;
                        }
                        jsb_sdk_m.sendMsg('IapSDK.purchase', JSON.stringify({ productId: iapProductInfo.productId }));
                    } else {
                        globalThis.LobbyManager.instance.customLoadingReasons.add(`iap_${iapProductInfo.flag}`);
                        Timer(2).subscribe(_ => {
                            globalThis.LobbyManager.instance.customLoadingReasons.delete(`iap_${iapProductInfo.flag}`);
                            observer.nextAndComplete({ status: 'success', id: null });
                        });
                    }
                }
            }
        });
    }

    restorePurchase() {
        if (sys.isNative) {
            if (sys.platform == sys.Platform.IOS) {
                jsb_sdk_m.sendMsg('IapSDK.restorePurchase', '');
            }
        }
    }

    canMake(args: string) {
        this.log('@canMake', args);
        let { productId } = JSON.parse(args);

        let iapStatItem = udm.iapStat.value[productId];
        if (iapStatItem == null) udm.iapStat.value[productId] = {};
        iapStatItem = udm.iapStat.value[productId];
        let BuyNum = iapStatItem.buyNum ?? 0;
        let RepeatTime = undefined;
        if (udm.iapBuyAt.value) {
            RepeatTime = (timem.now() - udm.iapBuyAt.value) / 1000 / 60;
        }

        let iapProductInfo = this.getIapProductInfoByProductId(productId);

        thinking_sdk_m.requestTrack('Shoping_Commodity_Buy', {
            Commodity_ID: iapProductInfo.flag,
            GiftType: iapProductInfo.giftType,
            BuyNum,
            RepeatTime,
            Level_ID: udm.stageNum.value,
            DifficultyLevel: 0,
            OpenWay: udm.openWay.value,
            IsNew: udm.isNew.value,
            Booster_Itemdetail: `Swapper:${udm.itemSwapper.value}|Magnet:${udm.itemMagnet.value}|Balloon:${udm.itemBalloon.value}`
        });
    }

    onPurchased(args: string) {
        this.log('onPurchased', args);
        let { id, productId } = JSON.parse(args);
        let observer = this._observerMap[productId];

        let iapProductInfo = this.getIapProductInfoByProductId(productId);

        udm.iapPurchasedTimes.value++;
        udm.iapPurchasedPrice.value += iapProductInfo.price;
        udm.save();

        thinking_sdk_m.requestUserAdd({
            Pay_money: iapProductInfo.price / 100,
            Pay_count: 1
        });

        appsflyer_sdk_m.logEvent('af_Purchase');

        udm.processingProductIds.value = udm.processingProductIds.value.filter(_ => _ != iapProductInfo.productId);
        udm.save();

        if (observer) observer.nextAndComplete({ status: 'success', id: `${id}` });
        else {

            let iapStatItem = udm.iapStat.value[iapProductInfo.productId];
            if (iapStatItem == null) udm.iapStat.value[iapProductInfo.productId] = {};
            iapStatItem = udm.iapStat.value[iapProductInfo.productId];
            let BuyNum = iapStatItem.buyNum ?? 0;
            let RepeatTime = undefined;
            if (udm.iapBuyAt.value) {
                RepeatTime = (timem.now() - udm.iapBuyAt.value) / 1000 / 60;
            }

            let Dill_ID = id ?? undefined;

            udm.provide(iapProductInfo.provide);

            // Timer(.2).subscribe(_ => { // 延迟打点是希望数据变动会导致的属性变化优先提交埋点，这样该iap埋点会包含变动之后数据
            thinking_sdk_m.requestTrack('Shoping_Commodity_Reward', {
                Commodity_ID: iapProductInfo.flag,
                GiftType: iapProductInfo.giftType,
                BuyNum,
                RepeatTime,
                CommodityItem: this.GetThinkingCommodityItem(iapProductInfo),
                Dill_ID,
                Level_ID: udm.stageNum.value,
                Value: iapProductInfo.price,
                DifficultyLevel: 0,
                Commodity_State: 'Normal',
                OpenWay: udm.openWay.value,
                IsNew: udm.isNew.value,
                Booster_Itemdetail: `Swapper:${udm.itemSwapper.value}|Magnet:${udm.itemMagnet.value}|Balloon:${udm.itemBalloon.value}`
            });
            // });

        }
    }

    onFailed(args: string) {
        this.log('onFailed', args);
        let { id, productId } = JSON.parse(args);

        udm.processingProductIds.value = []
        udm.save();

        let observer = this._observerMap[productId];
        if (observer) observer.nextAndComplete({ status: 'failed' });
    }

    onRestored(args: string) {
        this.log('onRestored', args);
        let { id, productId } = JSON.parse(args);

        udm.processingProductIds.value = []
        udm.save();

        let observer = this._observerMap[productId];
        if (observer) observer.nextAndComplete({ status: 'success', id: `${id}` });
        else {
            let iapProductInfo = this.getIapProductInfoByProductId(productId);

            let iapStatItem = udm.iapStat.value[iapProductInfo.productId];
            if (iapStatItem == null) udm.iapStat.value[iapProductInfo.productId] = {};
            iapStatItem = udm.iapStat.value[iapProductInfo.productId];
            let BuyNum = iapStatItem.buyNum ?? 0;
            let RepeatTime = undefined;
            if (udm.iapBuyAt.value) {
                RepeatTime = (timem.now() - udm.iapBuyAt.value) / 1000 / 60;
            }

            let Dill_ID = id ?? undefined;

            thinking_sdk_m.requestTrack('Shoping_Commodity_Reward', {
                Commodity_ID: iapProductInfo.flag,
                GiftType: iapProductInfo.giftType,
                BuyNum,
                RepeatTime,
                CommodityItem: this.GetThinkingCommodityItem(iapProductInfo),
                Dill_ID,
                Level_ID: udm.stageNum.value,
                Value: iapProductInfo.price,
                DifficultyLevel: 0,
                Commodity_State: 'Normal',
                OpenWay: udm.openWay.value,
                IsNew: udm.isNew.value,
                Booster_Itemdetail: `Swapper:${udm.itemSwapper.value}|Magnet:${udm.itemMagnet.value}|Balloon:${udm.itemBalloon.value}`
            });

            udm.provide(iapProductInfo.provide);
            globalThis.LobbyManager.instance.frontTipShow('Restored!');
        }
    }

    getIapProductInfoByProductId(productId): IapProductInfo {
        for (let key in DevConfig.iap) {
            let iapProductInfo = DevConfig.iap[key] as IapProductInfo;
            if (iapProductInfo.productId == productId) {
                return iapProductInfo;
            }
        }
    }

    GetThinkingCommodityItem(iapProductInfo: IapProductInfo) {
        let list: string[] = [];
        for (let key in iapProductInfo.provide) {
            let value = iapProductInfo.provide[key];
            if (['noads', 'coin', 'swapper', 'magnet', 'balloon', 'inf_heart_sec', 'noads_sec'].includes(key)) {
                list.push(`${key}:${value}`);
            } else if ('dynamic_reward_id' == key) {
                list.push(`coin:${udm.savingPot.value?.coin ?? 0}`);
            }
        }
        return list.join('|');
    }
}
globalThis.IapSDKManager = IapSDKManager;

export const iap_sdk_m = IapSDKManager.instance = new IapSDKManager();